<html>
<head><meta charset="utf-8"><title>Is this covariant? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html">Is this covariant?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="206726173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206726173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206726173">(Aug 12 2020 at 17:39)</a>:</h4>
<p>Could someone that understands the variance system explain why the <code>Foo</code> type here is coming out invariant instead of covariant? I am using <code>transmute</code> in my codebase to make it covariant anyway, but maybe the compiler has a point here and if so I would like to know what the reasoning is.</p>
<div class="codehilite"><pre><span></span><code><span class="k">enum</span> <span class="nc">Foo</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Nil</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Val</span><span class="p">(</span><span class="o">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="n">Foo</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">Fun</span><span class="p">(</span><span class="o">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="p">(</span><span class="k">dyn</span><span class="w"> </span><span class="nb">Fn</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="n">Foo</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="na">&#39;a</span><span class="p">)),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">const</span><span class="w"> </span><span class="n">NIL</span>: <span class="nc">Foo</span><span class="o">&lt;</span><span class="nb">&#39;static</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span>::<span class="n">Nil</span><span class="p">;</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">test_covariance</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">Foo</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">NIL</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="c1">// error</span>
</code></pre></div>



<a name="206730556"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206730556" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206730556">(Aug 12 2020 at 18:14)</a>:</h4>
<p>I'm not sure, but I reduced it to this:</p>
<div class="codehilite"><pre><span></span><code><span class="k">enum</span> <span class="nc">Foo</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Nil</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Fun</span><span class="p">(</span><span class="o">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="k">dyn</span><span class="w"> </span><span class="nb">Fn</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="p">()),</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="206730613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206730613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206730613">(Aug 12 2020 at 18:15)</a>:</h4>
<p>changing the <code>dyn Fn</code> to <code>fn</code> works</p>



<a name="206730838"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206730838" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206730838">(Aug 12 2020 at 18:16)</a>:</h4>
<p>AFAICS, the nomicon doesn't discuss trait object variance yet<br>
<a href="https://doc.rust-lang.org/nomicon/subtyping.html#variance">https://doc.rust-lang.org/nomicon/subtyping.html#variance</a></p>



<a name="206730907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206730907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Ani <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206730907">(Aug 12 2020 at 18:17)</a>:</h4>
<p>It seems like Rust doesn't allow</p>
<div class="codehilite"><pre><span></span><code>fn func&lt;&#39;a&gt;(f: Box&lt;dyn Fn() -&gt; &amp;&#39;static u32&gt;) -&gt; Box&lt;dyn Fn() -&gt; &amp;&#39;a u32&gt; {
    f
}
</code></pre></div>



<a name="206732140"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206732140" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Ani <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206732140">(Aug 12 2020 at 18:27)</a>:</h4>
<p>Replacing <code>f</code> with <code>Box::new(move || f())</code> works</p>



<a name="206733088"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206733088" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206733088">(Aug 12 2020 at 18:35)</a>:</h4>
<p>Trait objects are invariant iirc because the 'a could be used in an invariant position</p>



<a name="206733220"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206733220" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206733220">(Aug 12 2020 at 18:36)</a>:</h4>
<p>Hm reference says covariant...</p>



<a name="206733512"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206733512" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206733512">(Aug 12 2020 at 18:39)</a>:</h4>
<p>I think <a href="https://github.com/rust-lang/rust/blob/96b5dee9ab3b4b0c8f5086011b7a15b7c4aed48c/src/librustc_typeck/variance/constraints.rs#L330">this</a> is the relevant bit from rustc</p>



<a name="206733604"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206733604" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206733604">(Aug 12 2020 at 18:40)</a>:</h4>
<p>If I'm reading it right, it is covariant wrt <code>'a</code> in <code>dyn T + 'a</code>, but invariant wrt "projection bounds" in <code>T</code></p>



<a name="206733632"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206733632" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206733632">(Aug 12 2020 at 18:40)</a>:</h4>
<p>which I think means things like the <code>'a</code> in <code>T = Fn() -&gt; &amp;'a U</code></p>



<a name="206733774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206733774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206733774">(Aug 12 2020 at 18:41)</a>:</h4>
<p>There is this <a href="https://github.com/rust-lang/reference/pull/186#discussion_r161630407">https://github.com/rust-lang/reference/pull/186#discussion_r161630407</a></p>



<a name="206734466"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206734466" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206734466">(Aug 12 2020 at 18:47)</a>:</h4>
<p>Hm so that example compiles on stable, which reminds me of <a href="https://github.com/rust-lang/rust/issues/71550">https://github.com/rust-lang/rust/issues/71550</a></p>



<a name="206734746"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206734746" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206734746">(Aug 12 2020 at 18:49)</a>:</h4>
<p>You could ask in <a class="stream" data-stream-id="144729" href="/#narrow/stream/144729-wg-traits">#wg-traits</a> or <a class="stream" data-stream-id="213817" href="/#narrow/stream/213817-t-lang">#t-lang</a> but I suspect that for the function traits this is indeed fine; because like Iterator they're associated type is only an output</p>



<a name="206734830"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206734830" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206734830">(Aug 12 2020 at 18:50)</a>:</h4>
<p>But as Niko notes here <a href="https://github.com/rust-lang/rust/issues/71550#issuecomment-626722766">https://github.com/rust-lang/rust/issues/71550#issuecomment-626722766</a> that's not 100% clear and not currently implemented</p>



<a name="206734977"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206734977" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206734977">(Aug 12 2020 at 18:51)</a>:</h4>
<p>aside, I didn't realize the reference discussed variance, and that looks newer than the nomicon chapter -- maybe it should be removed/redirected from the nomicon?</p>



<a name="206735303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206735303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206735303">(Aug 12 2020 at 18:54)</a>:</h4>
<p>Okay so it sounds like this is actually fine, and rustc just isn't smart enough to know it</p>



<a name="206735416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206735416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206735416">(Aug 12 2020 at 18:55)</a>:</h4>
<p>although it does make things awkward since there is AFAIK no way to manually / unsafely override the variance on a publicly exported type</p>



<a name="206735816"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206735816" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206735816">(Aug 12 2020 at 18:58)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> I think that's true, but I would check with someone in wg-traits or t-lang, and we should perhaps document it in the nomicon. Submitting those docs would be a great way to check!</p>



<a name="206797015"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206797015" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206797015">(Aug 13 2020 at 09:49)</a>:</h4>
<p>AFAIK associated types are invariant, and return types of the <code>Fn*</code> traits are associated types</p>



<a name="206809584"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206809584" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206809584">(Aug 13 2020 at 12:41)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> yes but my impression is that associated types <em>could</em> be made not invariant in all cases, e.g., in this case where they're only used as an output (rather than an input to functions in the trait)</p>



<a name="206809597"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206809597" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206809597">(Aug 13 2020 at 12:41)</a>:</h4>
<p>but I'm not personally confident in that assessment</p>



<a name="206809795"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206809795" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206809795">(Aug 13 2020 at 12:43)</a>:</h4>
<p>ah I see. yes those are subtle questions.</p>



<a name="206815171"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206815171" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206815171">(Aug 13 2020 at 13:36)</a>:</h4>
<blockquote>
<p>yes but my impression is that associated types could be made not invariant in all cases</p>
</blockquote>
<p>in some cases they can, but it's hard to do this without accidentally causing unsoundness imo. <code>mem::Discriminant</code> is currently invariant because it has <code>&lt;T as DiscriminantKind&gt;::Discriminant</code> as a field. Theoretically <code>mem::Discriminant</code> could be bivariant but that's not possible rn</p>



<a name="206821565"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20this%20covariant%3F/near/206821565" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20this.20covariant.3F.html#206821565">(Aug 13 2020 at 14:30)</a>:</h4>
<p>yeah, associated types were made invariant in <a href="https://github.com/rust-lang/rust/pull/71896">https://github.com/rust-lang/rust/pull/71896</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>